use std::env;
use std::fs::File;
use std::io::{Read, Write};
use std::path::PathBuf;

fn modify(filename: PathBuf) -> std::io::Result<()> {
    let mut content = String::new();
    content.push_str("use core::prelude::rust_2018::derive;\n");
    content.push_str("use core::clone::Clone;\n");
    content.push_str("use core::marker::Copy;\n");

    let mut f = File::open(filename.as_path())?;
    let mut origin = String::new();
    let size = f.read_to_string(&mut origin)?;
    println!("read file size {}", size);
    origin = origin.replace("std::os::raw::", "core::ffi::");
    origin = origin.replace("::std::", "::core::");
    content.push_str(origin.as_str());

    let mut f1 = File::create(filename.as_path())?;
    f1.write_all(content.as_bytes())?;
    Ok(())
}

fn main() {
    let target = env::var("TARGET").expect("TARGET was not set");
    let os_type = if target.contains("linux") {
        "LINUX"
    } else {
        panic!("{} not support!", target);
    };
    let base_dir = format!("{}/c", env!("CARGO_MANIFEST_DIR"));
    let mut builder = cc::Build::new();
    builder.include(base_dir.as_str());
    for sf in vec!["cJSON.c"] {
        builder.file(format!("{}/{}", base_dir, sf));
    }
    builder.define(os_type, "1");
    builder.compile("mqtt_core");

    let bindings = bindgen::Builder::default()
        .header(format!("{}/cJSON.h", base_dir))
        .clang_arg(format!("-D{}=1", os_type))
        .clang_arg("-ffunction-sections")
        .clang_arg("-fdata-sections")
        .layout_tests(false)
        .parse_callbacks(Box::new(bindgen::CargoCallbacks))
        .generate()
        .expect("Unable to generate bindings");

    let out = PathBuf::from(format!("{}/src/ffi.rs", env!("CARGO_MANIFEST_DIR")));
    bindings
        .write_to_file(out.as_path())
        .expect("Couldn't write bindings!");

    modify(out).expect("modify binding failed");
}
